import os
import time
import asyncio
import aiofiles
from redisModel import RedisClient

class MeishitianxiaCSV:

    def __init__(self, saveDir):
        self.CSVDIR = saveDir
        self.csvFile = {}
        self.maxCSVOpen = 10
        self.maxCSVOpenTimeout = 1*60
        self.itemCount = 0
        self.categoryIndex = None
        self.redis_cli = RedisClient.get_redis()
        self.lock = asyncio.Lock()  # 添加锁来保护并发访问
        pass
        

    async def writeDishs(self, data):
        async with self.lock:
            for onePage in data:
                for dishName, dishImg, dishLink in zip(onePage['dish_names'], onePage['dish_imgs'], onePage['dish_links']):
                    # 使用 aiofiles 进行异步文件写入
                    await self.csvFile[self.categoryIndex][0].write(dishName + ',' + dishImg + ',' + dishLink +'\n')
                    # Redis 操作保持同步，因为 Redis 客户端本身就是同步的
                self.redis_cli.sadd(f'caipu:Meishitianxia:{self.categoryIndex}', onePage['page_url'])
                self.itemCount += 1
                if self.itemCount%20 == 0:
                    print(f'+ process_item {self.itemCount} {dishName} {dishLink}')
                


    async def openCsv(self, category):
        async with self.lock:
            if category not in self.csvFile:
                # 使用 aiofiles 打开文件
                f = await aiofiles.open(os.path.join(self.CSVDIR, category+'.csv'), 'a', encoding='utf-8')
                self.csvFile[category] = [f, time.time()]
            self.categoryIndex = category


    async def closeCsv(self):
        async with self.lock:
            to_close = [k for k, v in self.csvFile.items() if (time.time() - v[1]) > self.maxCSVOpenTimeout and v[0]]

            # 统一处理关闭和删除
            for k in to_close:
                if self.csvFile[k][0]:
                    await self.csvFile[k][0].close()
                del self.csvFile[k]
            
            to_close = []
            if len(self.csvFile) > self.maxCSVOpen:
                sorted_csvFile = sorted(self.csvFile.items(), key=lambda item: item[1][1])
                need_close = len(self.csvFile) - self.maxCSVOpen
                to_close.extend([item[0] for item in sorted_csvFile[:need_close]])
            
            for k in to_close:
                if self.csvFile[k][0]:
                    await self.csvFile[k][0].close()
                del self.csvFile[k]